const authCodeFunc = require('../../../utils/authCode');
const User = require('../../../models/admin_users');
const Role = require('../../../models/admin_role');
const UserOrRole = require('../../../models/admin_user_or_role');
const utilsTest = require('../../../utils/validate');
const knex = require('../../../models/knex');

/**
 * 用户管理控制器
 */
const ControllerUser = {
    /* 获取用户列表 */
    getList: async function (req, res, next) {
        try {
            let { per_page, page, keywor, } = req.query;
            let offset = (per_page * (page - 1)) || 0; //计算当前页
            let user_role = UserOrRole.table;
            let users = User.table;
            let roles = Role.table;
            let key = `${users}.user_name`;

            keywor = decodeURI(keywor); // 对前端传递过来的信息进行解码

            if (utilsTest.isPhone(keywor)) key = `${users}.user_phone`;

            const list = await knex(user_role)
                .join(users, `${user_role}.user_id`, `${users}.id`)
                .join(roles, `${user_role}.role_id`, `${roles}.id`)
                .where(key, 'like', `%${keywor}%`) // 条件搜索
                .limit(Number(per_page)).offset(Number(offset)) // 分页查询
                .select(
                    `${users}.id`, `${users}.user_account`, `${users}.user_name`,
                    `${users}.user_avatar_url`, `${users}.user_email`, `${users}.user_phone`,
                    `${users}.status`, `${users}.created_at`,
                    `${user_role}.role_id`, `${roles}.name as role_name`,
                )

            let total = (await User.all()).length;
            let number = Math.ceil(total / per_page); // 计算出信息总页数

            res.json({ code: 200, data: { list, total, number } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 获取用户详情 */
    getById: async function (req, res, next) {
        try {
            let { id } = req.query;

            const users = await User.select({ id });

            const user_role = await UserOrRole.select({ user_id: id })

            let role_id = user_role[0].role_id;

            const roles = await Role.select({ id: role_id });

            let user = users[0];

            let data = {
                account: user.user_account,
                role_id: roles[0].id,
                avatar: user.user_avatar_url,
                name: user.user_name,
                email: user.user_email,
                phone: user.user_phone,
                status: user.status,
            }

            res.json({ code: 200, data: data })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 创建 */
    Insert: async function (req, res, next) {
        try {
            let { role_id, account, password, name, avatarUrl, email, phone, status } = req.body;
            let params = {
                user_account: account,
                user_password: authCodeFunc(password, 'ENCODE'),
                user_phone: phone,
                status: Number(status),
                created_at: new Date().getTime()
            }

            const user = await User.select({ user_account: account });

            const isPhone = await User.select({ user_phone: phone });

            if (user.length > 0) return res.json({ code: 0, msg: '该用户已存在' });

            if (isPhone.length > 0) return res.json({ code: 0, msg: "该手机号已被注册" });

            if (email) if (!utilsTest.isEmail(email)) return res.json({ code: 0, msg: "请输入正确的电子邮件" });

            if (!role_id && !account && !phone && !password) return res.json({ code: 0, msg: "角色、账号、手机号、密码必填" });

            if (!account) return res.json({ code: 0, msg: "请设置用户账号" });

            if (!phone) return res.json({ code: 0, msg: "请输入手机号码" });

            if (!password) return res.json({ code: 0, msg: "请设置密码" });

            if (!role_id) return res.json({ code: 0, msg: "请选择角色" });

            if (!utilsTest.inSmallEnglish(account)) return res.json({ code: 0, msg: "账号必须为长度5-12位小写英文字符" });

            if (!utilsTest.isPhone(phone)) return res.json({ code: 0, msg: "请输入正确的手机号码" });

            if (!utilsTest.isPassword(password)) return res.json({ cpde: 0, msg: "密码须长度8-16位数并且需要小写字母+数组组合" });

            if (name) params.user_name = name;

            if (email) params.user_email = email;

            if (avatarUrl) params.user_avatar_url = avatarUrl;

            const users = await User.insert(params);

            let user_id = users[0];

            await UserOrRole.insert({ user_id, role_id });

            res.json({ code: 200, msg: "新增用户成功" })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 用户管理修改用户信息 */
    update: async function (req, res, next) {
        try {
            let { role_id, account, name, avatarUrl, email, phone, status, id } = req.body;

            let params = {
                user_account: account,
                user_phone: phone,
                status: Number(status),
                updated_at: new Date().getTime()
            }

            const users = await User.all()

            const user_role = await UserOrRole.select({ user_id: id });

            users.splice(users.findIndex(e => e.id === id), 1); // 筛选除本id外的所有用户
            let phoneMime = users.some(e => e.user_phone === phone); // 检索筛选的用户中有没有使用该手机号
            let accountMime = users.some(e => e.user_account === account); // 检索筛选的用户中有没有使用该手机号

            let user_role_id = user_role[0].id;

            if (phoneMime) return res.json({ code: 0, msg: "该手机号已被使用" });

            if (accountMime) return res.json({ code: 0, msg: "该用户名已被使用" });

            if (email) if (!utilsTest.isEmail(email)) return res.json({ code: 0, msg: "请输入正确的电子邮件" });

            if (!role_id && !account && !phone) return res.json({ code: 0, msg: "角色、账号、手机号必填" });

            if (!account) return res.json({ code: 0, msg: "请设置用户账号" });

            if (!phone) return res.json({ code: 0, msg: "请输入手机号码" });

            if (!role_id) return res.json({ code: 0, msg: "请选择角色" });

            if (!utilsTest.inSmallEnglish(account)) return res.json({ code: 0, msg: "账号必须为长度5-12位小写英文字符" });

            if (!utilsTest.isPhone(phone)) return res.json({ code: 0, msg: "请输入正确的手机号码" });

            if (name) params.user_name = name;

            if (email) params.user_email = email;

            if (avatarUrl) params.user_avatar_url = avatarUrl;

            await UserOrRole.update(user_role_id, { role_id });

            await User.update(id, params);

            res.json({ code: 200, msg: '编辑成功' })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 删除 */
    del: async function (req, res, next) {
        try {
            let { id } = req.body;
            let authorization = req.headers.authorization;
            let token = authorization.split(' ');
            let user_decode = authCodeFunc(token[1], 'DECODE');
            let user_info = user_decode.str.split('\t');
            const user_role = await UserOrRole.select({ user_id: id })
            let user_role_id = user_role[0].id;

            if (id === Number(user_info[0])) return res.json({ code: 0, msg: "不能删除自己" })
            if (user_role[0].role_id == 1) return res.json({ code: 0, msg: "博主不能删除" })

            await UserOrRole.delete(user_role_id)
            await User.delete(id)

            res.json({ code: 200, msg: '删除成功' })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 获取角色列表 */
    getRoleList: async function (req, res, next) {
        try {
            const roles = await Role.select({ status: 1 });

            res.json({ code: 200, data: roles })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 用户个人修改信息 */
    updateInfo: async function (req, res, next) {
        try {
            let authorization = req.headers.authorization;
            let tokens = authorization.split(' ');
            let user_decode = authCodeFunc(tokens[1], 'DECODE');
            let user_info = user_decode.str.split('\t');
            let id = user_info[0];

            let params = { updated_at: new Date().getTime() };
            let { name, phone, email, avatar } = req.body;

            if (!name && !phone && !email && !avatar) return res.json({ code: 0, msg: "没有任何修改" })

            if (name) params.user_name = name;

            if (phone) params.user_phone = phone;

            if (email) params.user_email = email;

            if (avatar) params.user_avatar_url = avatar;

            await User.update(id, params);

            const users = await User.select({ id });
            const user = users[0];
            let auth_Code = id + '\t' + user.user_email + '\t' + user_info[2];
            const token = authCodeFunc(auth_Code, 'ENCODE');

            const user_role = await UserOrRole.select({ user_id: id })
            let role_id = user_role[0].role_id;
            const roles = await Role.select({ id: role_id });
            let userInfo = {
                account: user.user_account,
                role_name: roles[0].name,
                avatar: user.user_avatar_url,
                name: user.user_name,
            }

            res.json({ code: 200, msg: '修改成功', data: { token, userInfo } })
        } catch (e) {
            res.json({ code: 0, msg: e })
        }
    },

    /* 用户个人密码修改 */
    updatePassword: async function (req, res, next) {
        try {
            let authorization = req.headers.authorization;
            let tokens = authorization.split(' ');
            let user_decode = authCodeFunc(tokens[1], 'DECODE');
            let user_info = user_decode.str.split('\t');
            let id = user_info[0];
            let oldPassword = authCodeFunc(user_info[1], 'DECODE').str; // 旧密码

            let { password, newPwd, okpassword } = req.body;

            let params = { user_password: authCodeFunc(newPwd, 'ENCODE'), updated_at: new Date().getTime() };

            if (oldPassword != password) return res.json({ code: 0, msg: "输入的原密码错误" });

            if (user_info[2] === newPwd) return res.json({ code: 0, msg: "新密码不能与原密码一致" });

            if (newPwd != okpassword) return res.json({ code: 0, msg: "确认密码与新密码不一致" });

            let auth_Code = id + '\t' + params.user_password;

            const token = authCodeFunc(auth_Code, 'ENCODE');

            await User.update(id, params)

            res.json({ code: 200, msg: "修改密码成功", data: { token } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    }
}

module.exports = ControllerUser;
